package it.biffi.jirc.bot.service;

import it.biffi.jirc.bot.BotException;
import it.biffi.jirc.bot.FileTransferBot;
import it.biffi.jirc.bot.FileTransferConfig;
import it.biffi.jirc.bot.listener.FileTransferFinishListener;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import javax.jws.Oneway;

import org.jibble.pircbot.DccFileTransfer;

public class Service {

	private ServiceCallback callback;
	private int perc;
	private FileTransferBot bot;

	public void stop() {
		if (bot != null) {
			try {
				bot.sendMessage(bot.getConfig().getSourcePeer(), "xdcc cancel");
				bot.sendMessage(bot.getConfig().getSourcePeer(), "xdcc remove");
				bot.stop();
			} catch (Exception e) {
				bot.stop();
			}
		}
	}

	public boolean start(final String server, final String channel,
			final String nick, final String packet, String outputPath,
			long timeout) throws BotException {
		bot = new FileTransferBot();
		String name = UUID.randomUUID().toString();

		boolean connected = bot.connect("[Bot" + name.substring(0, 5) + "]",
				server, 30000);
		// System.out.println("connected: " + connected);
		if (!connected) {
			if (callback != null) {
				callback.onInterrupeted();
			}
			return false;
		}
		if (connected) {
			if (callback != null) {
				callback.onConnected();
			}
		}
		FileTransferConfig config = new FileTransferConfig();
		config.setSourceChannel(channel);
		config.setSourcePeer(nick);
		config.setInputCommand("xdcc send #" + packet);
		config.setStartTimeout(timeout);
		config.setOutputPath(outputPath);
		bot.start(config);
		// System.out.println("bot started on requested channel: "
		// + config.getSourceChannel());
		// System.out.println("REQUESTING PACKET");
		final Timer t = new Timer("PollTrasnferState", true);
		final DccFileTransfer transfer = bot.requestPacket(
				config.getStartTimeout(), new FileTransferFinishListener() {

					@Override
					public void onFinish(Exception finishedWithThisError) {
						if (finishedWithThisError == null) {
							// System.out.println("FINISH TRANSFER SUCCESS");
							if (callback != null) {
								callback.onFinish();
							}
						} else {
							// System.out.println("FINISH TRANSFER ERROR");
							finishedWithThisError.printStackTrace();
							t.cancel();
							if (callback != null) {
								callback.onInterrupeted();
							}
						}

					}
				});
		if (transfer != null) {
			File file = new File(config.getOutputPath() + "/"
					+ transfer.getFile().getName());
			// System.out.println("Receiveing file: " + file.getAbsolutePath());
			// System.out.println("Receiveing file: " + file.getAbsolutePath());
			transfer.receive(file, true);
			if (connected) {
				if (callback != null) {
					callback.onStarted();
				}
			}
			t.scheduleAtFixedRate(new TimerTask() {

				@Override
				public void run() {
					int perc = (int) transfer.getProgressPercentage();
					int rate = (int) transfer.getTransferRate();
					if (Service.this.perc != perc) {
						Service.this.perc = perc;
						if (callback != null) {
							callback.onProgress(perc);
						}
					}
					// System.out.println("Trasnfer state: " + perc + "%"
					// + "rate: " + rate);
				}
			}, 0, 5000);
		} else {
			// System.out.println("Request packet failed");
			if (this.callback != null) {
				callback.onInterrupeted();
			}

		}

		return connected;
	}

	public ServiceCallback getCallback() {
		return callback;
	}

	public void setCallback(ServiceCallback callback) {
		this.callback = callback;
	}

}
